#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <stdint.h>
#include <stdio.h>

#include <iostream>

using namespace std;

const GLuint WIDTH = 800, HEIGHT = 600;

void process_input_callback(GLFWwindow *window, int key, int scancode, int action, int mods) {
  if (key == GLFW_KEY_0 && action == GLFW_PRESS) {
    cout << "key press" << endl;
  }
}

int main() {
  std::cout << "hello world" << endl;

  // init glfw
  glfwInit();

  // set the default require options, config the gl
  //glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  //glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
  //glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  // this line is important for new version of opengl now
  //glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
  // set the window
  glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);

  GLFWwindow *window = glfwCreateWindow(WIDTH, HEIGHT, "GUILITE", nullptr, nullptr);
  if (window == nullptr) {
    std::cout << "Failed to create GLFW window" << std::endl;
    glfwTerminate();
    return -1;
  }

  // make the windows to the current thread
  glfwMakeContextCurrent(window);
  if (GLEW_OK != glewInit()) {
    std::cout << "Glew init failed" << std::endl;
  }

  // set the call back
  glfwSetKeyCallback(window, process_input_callback);
  std::cout << glGetString(GL_VERSION) << std::endl;

  // clang-format off
  float positions[] = {
    -0.5f, -0.5f,
     0.0f,  0.5f, 
     0.5f, -0.5f
     };
  // clang-format on
  // initial the resource
  unsigned int buffer;
  glGenBuffers(1, &buffer);
  glBindBuffer(GL_ARRAY_BUFFER, buffer);
  glBufferData(GL_ARRAY_BUFFER,6*sizeof(float),positions,GL_STATIC_DRAW);

  // atrribute
  glEnableVertexAttribArray(0);
  glVertexAttribPointer(0,2,GL_FLOAT,GL_FALSE,2*sizeof(float),(void*)0);

  glBindBuffer(GL_ARRAY_BUFFER,0);
  // event loop
  while (!glfwWindowShouldClose(window)) {
    /* Render */
    glClear(GL_COLOR_BUFFER_BIT);

    glDrawArrays(GL_TRIANGLES,0,3);
    // Swap the screen buffers
    glfwSwapBuffers(window);
    glfwPollEvents();
  }

  // Terminate GLFW, clearing any resources allocated by GLFW.
  glfwTerminate();
  return 0;
}